package com.yznote.cloudesk.websocket.service.impl;

import com.alibaba.fastjson.JSON;
import com.yznote.cloudesk.common.constants.YCacheConstant;
import com.yznote.cloudesk.common.exception.YException;
import com.yznote.cloudesk.common.oss.OssUtils;
import com.yznote.cloudesk.common.pojo.Friend;
import com.yznote.cloudesk.common.pojo.Message;
import com.yznote.cloudesk.common.pojo.TempStorage;
import com.yznote.cloudesk.common.tokenShare.YTokenShare;
import com.yznote.cloudesk.common.utils.IdUtils;
import com.yznote.cloudesk.cache.yCache.YCache;
import com.yznote.cloudesk.message.mapper.FriendMapper;
import com.yznote.cloudesk.message.mapper.RoomMapper;
import com.yznote.cloudesk.message.mapper.TempMapper;
import com.yznote.cloudesk.user.mapper.UserMapper;
import com.yznote.cloudesk.websocket.server.YDWebSocketSession;
import com.yznote.cloudesk.websocket.service.WebSocketService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class WebSocketServiceImpl implements WebSocketService {

    @Autowired
    YTokenShare yTokenShare;
    @Autowired
    RocketMQTemplate rocketMQTemplate;
    @Autowired
    YCache yCache;
    @Autowired
    RoomMapper roomMapper;
    @Autowired
    OssUtils ossUtils;
    @Autowired
    TempMapper tempMapper;
    @Autowired
    FriendMapper friendMapper;
    @Autowired
    UserMapper userMapper;

    @Override
    public Boolean sendMsgToRoom(Message message) {
        if (message.getRoomId() == null || message.getMessageContent() == null) {
            return false;
        }
        LocalDateTime now = LocalDateTime.now();
        // 设置消息id
        message.setMessageId(IdUtils.nextId());
        // 设置消息状态
        message.setMessageStatus(0);
        // 文本消息
        // 一些额外字段
        message.setMessageType(0);
        message.setUpdateTime(now);
        message.setCreateTime(now);
        messageToRocket(message);
        // 获得房间的用户列表
        // 这里需要提前缓存
        List<Long> users = (List<Long>) yCache.tryGet(YCacheConstant.OTHER,message.getRoomId().toString());
        if (users == null) {
            // 从数据库里面获取
            users = roomMapper.queryRoomUserIdList(message.getRoomId());
            // 放入缓存
            yCache.put(YCacheConstant.OTHER,message.getRoomId().toString(), users);
        }
        for (Long aLong : users) {
            try {
                YDWebSocketSession.sendMsg(message, aLong);
            } catch (Exception e) {
                // 用户不在线
            }
        }
        return true;
    }

    @Override
    public Boolean sendMsgToFriend(Message message) {
        Long friendUserId = message.getFriendUserId();
        if (friendUserId == null || message.getMessageContent() == null) {
            return false;
        }
        if (userMapper.getUserMsg(friendUserId) == null) {
            throw new YException("此用户不存在", 500);
        }
        // 判断对方对发送方的好友状态
        Friend friendMessage = friendMapper.getFriendMessage(message.getCreateBy(),friendUserId);

        if (friendMessage != null && !friendMessage.getStatus().equals(1)) {
            throw new YException("你们还不是好友", 500);
        }
        LocalDateTime now = LocalDateTime.now();
        // 设置消息id
        message.setMessageId(IdUtils.nextId());
        // 设置消息状态
        message.setMessageStatus(0);
        // 文本消息
        // 一些额外字段
        message.setMessageType(0);
        message.setUpdateTime(now);
        message.setCreateTime(now);
        try {
            YDWebSocketSession.sendMsg(message, message.getFriendUserId());
        } catch (Exception e) {
            // 用户不在线
        }
        messageToRocket(message);
        return true;
    }

    @Override
    public Boolean sendMsgToFriendWithFile(Message message, MultipartFile mtf) throws Exception {
        Long userId = message.getCreateBy();
        Long friendUserId = message.getFriendUserId();
        if (friendUserId == null || message.getMessageContent() == null) {
            return false;
        }
        if (userMapper.getUserMsg(friendUserId) == null) {
            throw new YException("此用户不存在", 500);
        }
        // 判断对方对发送方的好友状态
        Friend friendMessage = friendMapper.getFriendMessage(userId,friendUserId);

        if (friendMessage != null && !friendMessage.getStatus().equals(1)) {
            throw new YException("你们还不是好友", 500);
        }
        Long messageId = IdUtils.nextId();
        LocalDateTime now = LocalDateTime.now();
        // 设置消息id
        message.setMessageId(messageId);
        // 设置消息状态
        message.setMessageStatus(0);
        // 文件消息
        message.setMessageType(2);
        message.setUpdateTime(now);
        message.setCreateTime(now);
        //上传至临时文件夹
        byte[] bytes;
        bytes = mtf.getBytes();
        Long fileId = IdUtils.nextId();
        String name = mtf.getOriginalFilename();
        TempStorage tempStorage = new TempStorage();
        tempStorage.setUserId(userId);
        tempStorage.setFileId(fileId);
        tempStorage.setMessageId(messageId);
        tempStorage.setIsFriend(1);
        tempStorage.setMemory((long) bytes.length);
        String path = "filesystem/" + "tempStorage/" + fileId + name.substring(name.lastIndexOf("."));
        //文件默认保存1周
        tempStorage.setSaveTime((long) 60 * 60 * 24 * 7);
        tempStorage.setFilePath(path);
        tempStorage.setCreateTime(now);
        tempStorage.setStatus(0);
        tempStorage.setReceiveId(message.getFriendUserId());
        tempStorage.setCreateBy(userId);
        tempMapper.insertTemp(tempStorage);
        ossUtils.pushFileSource(bytes, path);
        try {
            YDWebSocketSession.sendMsg(message, message.getFriendUserId());
        } catch (Exception e) {
            // 用户不在线
        }
        messageToRocket(message);
        return true;
    }

    /**
     * 发送至消息队列 进行异步持久化
     */
    public void messageToRocket(Message message) {
        rocketMQTemplate.asyncSend("messageToMysql", JSON.toJSONString(message), new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
            }

            @Override
            public void onException(Throwable throwable) {
                log.error("rocketmq error!" + "-messageId:" + message.getMessageId());
            }
        }, 10000L);
    }

}
